package com.ruoyi.util;

import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.ruoyi.DynamicClassInfo;
import com.ruoyi.common.annotation.DynamicAnnotation;
import com.ruoyi.common.exception.CustomException;
import com.ruoyi.sql.TableUtil;
import com.ruoyi.sql.WhereEntity;
import lombok.extern.slf4j.Slf4j;

import java.lang.reflect.Field;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

/**
 * **********************
 * * Author: XiaShiLong *
 * * Date  : 2021-04-10 *
 * * Time  : 09:58      *
 * * to    : lz&xm      *
 * **********************
 * 动态工具类
 **/
@Slf4j
public class DynamicUtil {

    /**
     * 解析对象
     *
     * @param classPath 对象路径
     * @param associate true:关联对象解析,false:关联对象不解析
     * @return ClassInfo
     */
    public static DynamicClassInfo resolveClass(String classPath, boolean associate) {
        Class<?> clz = ReflectUtil.getClass(classPath);
        AtomicInteger index = new AtomicInteger(0);
        String tableName = TableUtil.getTableName(clz);
        List<DynamicClassInfo.FieldInfo> customizeClassColumnList = new ArrayList<>();
        List<DynamicClassInfo.FieldInfo> fieldInfoList = Arrays.stream(ReflectUtil.getFieldHaveSuperclass(clz))
                .filter(f -> !f.getName().equals("serialVersionUID") && null != f.getAnnotation(DynamicAnnotation.class))
                .map(
                        f -> {
                            f.setAccessible(true);
                            DynamicAnnotation annotation = f.getAnnotation(DynamicAnnotation.class);
                            //自定义对象字段处理
                            if (associate && annotation.isCustomizeClass()) {
                                //获取配置要显示的属性名
                                DynamicAnnotation.CustomizeClassFields[] customizeClassFields = annotation.showColumnList();
                                //获取关联对象的类型
                                Class<?> type = f.getType();
                                //配置显示的列
                                for (DynamicAnnotation.CustomizeClassFields name : customizeClassFields) {
                                    if (null != name) {
                                        Field field;
                                        try {
                                            field = type.getDeclaredField(name.columnName());
                                        } catch (NoSuchFieldException e) {
                                            log.error("未找到属性!");
                                            throw new CustomException("未找到属性");
                                        }
                                        customizeClassColumnList.add(
                                                DynamicClassInfo.FieldInfo.builder()
                                                        .attributeName(f.getName() + "." + name.columnName())
                                                        .attributeNameCh(name.columnNameCh())
                                                        .tableName(type.getAnnotation(TableName.class).value())
                                                        .tableColumnName(StringUtils.camelToUnderline(name.columnName()))
                                                        .type(field.getType().getSimpleName())
                                                        .sort(index.getAndIncrement())
                                                        .radio(annotation.isRadio())
                                                        .build()
                                        );
                                    }
                                }
                                return null;
                            } else if (!annotation.isCustomizeClass()) {
                                //正常字段处理
                                return DynamicClassInfo.FieldInfo.builder()
                                        .attributeName(f.getName())
                                        .attributeNameCh(annotation.value())
                                        .tableName(tableName)
                                        .tableColumnName(StringUtils.camelToUnderline(f.getName()))
                                        .type(f.getType().getSimpleName())
                                        .sort(index.getAndIncrement())
                                        .radio(annotation.isRadio())
                                        .build();
                            } else {
                                return null;
                            }
                        }
                ).collect(Collectors.toList());
        fieldInfoList.removeIf(Objects::isNull);
        if (!customizeClassColumnList.isEmpty()) {
            fieldInfoList.addAll(customizeClassColumnList);
        }
        fieldInfoList.sort(Comparator.comparing(DynamicClassInfo.FieldInfo::getSort));
        return DynamicClassInfo
                .builder()
                .simpleName(clz.getSimpleName())
                .classPath(clz.getName())
                .fieldInfoList(fieldInfoList)
                .fieldNumber(fieldInfoList.size())
                .build();
    }

    /**
     * 动态查询条件拼接
     *
     * @param w  条件对象
     * @param sb sql
     */
    public static void queryTypeWhere(WhereEntity w, StringBuilder sb) {
        switch (w.getDictQueryType()) {
            case 0:
                StringBuilder s = new StringBuilder();
                String[] split = w.getValue1().split(",");
                for (String st : split) {
                    s.append("\"").append(st).append("\"").append(",");
                }
                s.deleteCharAt(s.length() - 1);
                sb.append("AND ").append(w.getTableName()).append(".").append(w.getColumnName()).append(" IN ( ").append(s.toString()).append(" ) ");
                break;
            case 1:
                sb.append("AND ").append(w.getTableName()).append(".").append(w.getColumnName()).append(" = \"").append(w.getValue1()).append("\" ");
                break;
            case 2:
                sb.append("AND ").append(w.getTableName()).append(".").append(w.getColumnName()).append(" LIKE \"").append(w.getValue1()).append("%\" ");
                break;
            case 3:
                sb.append("AND ").append(w.getTableName()).append(".").append(w.getColumnName()).append(" != \"").append(w.getValue1()).append("\" ");
                break;
            case 4:
                sb.append("AND (").append(w.getTableName()).append(".").append(w.getColumnName()).append(" >= \"").append(w.getValue1()).append("\" && ").append(w.getTableName()).append(".").append(w.getColumnName()).append("<=\"").append(w.getValue2()).append("\") ");
                break;
        }
    }
}
